Fix passing --extern and -L to doc tests
authorAlex Crichton <alex@alexcrichton.com>
Wed, 25 Mar 2015 19:46:21 +0000 (12:46 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Tue, 31 Mar 2015 17:06:46 +0000 (10:06 -0700)
Previously --extern was passed for *all* upstream dependencies, causing
conflicts if some had duplicate names. Now cargo only passes --extern for
libraries that were built including immediate dependencies. Cargo also
additionally now properly passes `-L dependency=` instead of just a plain `-L`.

Closes #1449

src/cargo/ops/cargo_rustc/compilation.rs
src/cargo/ops/cargo_rustc/fingerprint.rs
src/cargo/ops/cargo_rustc/mod.rs
src/cargo/ops/cargo_test.rs
tests/test_cargo_compile_git_deps.rs
tests/test_cargo_test.rs

index 9e23fb60f2137a44eae013945b0f91f951f8d0b4..f5d384ebf07625bda9c9869586014b8c142f4b78 100644 (file)
@@ -14,7 +14,7 @@ pub struct Compilation {
     ///
     /// This is currently used for passing --extern flags to rustdoc tests later
     /// on.
-    pub libraries: HashMap<PackageId, Vec<PathBuf>>,
+    pub libraries: HashMap<PackageId, Vec<(String, PathBuf)>>,
 
     /// An array of all tests created during this compilation.
     pub tests: Vec<(String, PathBuf)>,
index 5ac3c6779d2bd90df4094435dbb1db128905fefb..2dacbb3d6904dadfdee8338de45b9af47847657d 100644 (file)
@@ -58,18 +58,7 @@ pub fn prepare_target<'a, 'b>(cx: &mut Context<'a, 'b>,
     let mut missing_outputs = false;
     if !profile.doc {
         for filename in try!(cx.target_filenames(target, profile)).iter() {
-            let dst = root.join(filename);
-            missing_outputs |= fs::metadata(&dst).is_err();
-
-            if profile.test {
-                cx.compilation.tests.push((target.name().to_string(), dst));
-            } else if target.is_bin() || target.is_example() {
-                cx.compilation.binaries.push(dst);
-            } else if target.is_lib() {
-                let pkgid = pkg.package_id().clone();
-                cx.compilation.libraries.entry(pkgid).or_insert(Vec::new())
-                  .push(dst);
-            }
+            missing_outputs |= fs::metadata(root.join(filename)).is_err();
         }
     }
 
index c553547e7924c313b2a598f62616c701c8939f78..0415a9c7c3e3984ad58d16e6a56108163df9fdca 100644 (file)
@@ -132,6 +132,38 @@ pub fn compile_targets<'a, 'b>(targets: &[(&'a Target, &'a Profile)],
                     .display().to_string();
     cx.compilation.extra_env.insert("OUT_DIR".to_string(), out_dir);
 
+    for &(target, profile) in targets {
+        for filename in try!(cx.target_filenames(target, profile)).iter() {
+            let dst = cx.out_dir(pkg, Kind::Target, target).join(filename);
+            if profile.test {
+                cx.compilation.tests.push((target.name().to_string(), dst));
+            } else if target.is_bin() || target.is_example() {
+                cx.compilation.binaries.push(dst);
+            } else if target.is_lib() {
+                let pkgid = pkg.package_id().clone();
+                cx.compilation.libraries.entry(pkgid).or_insert(Vec::new())
+                  .push((target.crate_name(), dst));
+                if !target.is_lib() { continue }
+
+                // Include immediate lib deps as well
+                for dep in cx.dep_targets(pkg, target, profile).iter() {
+                    let (pkg, target, profile) = *dep;
+                    let pkgid = pkg.package_id();
+                    if !target.is_lib() { continue }
+                    if profile.doc { continue }
+                    if cx.compilation.libraries.contains_key(&pkgid) { continue }
+
+                    let v = try!(cx.target_filenames(target, profile));
+                    let v = v.into_iter().map(|f| {
+                        (target.crate_name(),
+                         cx.out_dir(pkg, Kind::Target, target).join(f))
+                    }).collect::<Vec<_>>();
+                    cx.compilation.libraries.insert(pkgid.clone(), v);
+                }
+            }
+        }
+    }
+
     if let Some(feats) = cx.resolve.features(pkg.package_id()) {
         cx.compilation.features.extend(feats.iter().cloned());
     }
index ff9f4dd610f14761738d1d96f69f8de979acf795..e32807e8d038993e43e2af958e378c9d2efd8ea5 100644 (file)
@@ -31,8 +31,11 @@ pub fn run_tests(manifest_path: &Path,
         let mut p = try!(compile.rustdoc_process(&compile.package));
         p.arg("--test").arg(lib)
          .arg("--crate-name").arg(&crate_name)
-         .arg("-L").arg(&compile.root_output)
-         .arg("-L").arg(&compile.deps_output)
+         .arg("-L").arg(&{
+             let mut arg = OsString::from("dependency=");
+             arg.push(&compile.deps_output);
+             arg
+         })
          .cwd(compile.package.root());
 
         if test_args.len() > 0 {
@@ -43,9 +46,9 @@ pub fn run_tests(manifest_path: &Path,
             p.arg("--cfg").arg(&format!("feature=\"{}\"", feat));
         }
 
-        for (pkg, libs) in compile.libraries.iter() {
-            for lib in libs.iter() {
-                let mut arg = OsString::from(pkg.name());
+        for (_, libs) in compile.libraries.iter() {
+            for &(ref name, ref lib) in libs.iter() {
+                let mut arg = OsString::from(name);
                 arg.push("=");
                 arg.push(lib);
                 p.arg("--extern").arg(&arg);
index f1ce6ec0079e2114b6a4dbab592937d0733d78cb..4ea280cf3a87e7bb39b1aa32df8250d466472041 100644 (file)
@@ -1674,3 +1674,45 @@ test!(dont_require_submodules_are_checked_out {
     assert_that(git1.cargo("build").arg("-v").cwd(&dst),
                 execs().with_status(0));
 });
+
+test!(doctest_same_name {
+    let a2 = git_repo("a2", |p| {
+        p.file("Cargo.toml", r#"
+            [project]
+            name = "a"
+            version = "0.5.0"
+            authors = []
+        "#)
+        .file("src/lib.rs", "pub fn a2() {}")
+    }).unwrap();
+
+    let a1 = git_repo("a1", |p| {
+        p.file("Cargo.toml", &format!(r#"
+            [project]
+            name = "a"
+            version = "0.5.0"
+            authors = []
+            [dependencies]
+            a = {{ git = '{}' }}
+        "#, a2.url()))
+        .file("src/lib.rs", "extern crate a; pub fn a1() {}")
+    }).unwrap();
+
+    let p = project("foo")
+        .file("Cargo.toml", &format!(r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+
+            [dependencies]
+            a = {{ git = '{}' }}
+        "#, a1.url()))
+        .file("src/lib.rs", r#"
+            #[macro_use]
+            extern crate a;
+        "#);
+
+    assert_that(p.cargo_process("test").arg("-v"),
+                execs().with_status(0));
+});
index 6cec47e39feba8a06679103afe3d42564acfe27f..6cf457aee0a25cd6aad58ace0d88480916ba8b00 100644 (file)
@@ -1416,6 +1416,6 @@ test!(dashes_to_underscores {
             pub fn foo() -> i32 { 1 }
         "#);
 
-    assert_that(p.cargo_process("test"),
+    assert_that(p.cargo_process("test").arg("-v"),
                 execs().with_status(0));
 });